'''
Created on Mar 14, 2010

@author: rax
'''

import unittest

from utils import DEFAULT_PARAMETERS, call_view, create_request, is_resolver, create_user
from django.http import Http404, HttpRequest


class State(object):

    assignment_patterns = DEFAULT_PARAMETERS

    def __init__(self, url, method, *argv, **kvargs):
        self.url = url
        
        if method not in ('GET', 'POST'):
            raise AssertionError("Invalid request medod: %s. " + 
                    "Method can only be GET or POST." % method)
        self.method = method
    
    
    def set_up(self):
        self.user = create_user()
        
    def verify(self):
        pass
    
    def tear_down(self):
        pass
        
    def run(self):
        if is_resolver(self.url):
            raise AssertionError(
                    "Url %s cannot be an instance of RegexURLResolver."
                    % self.url)
        else:
            url_regex = self.url.regex
            view = self.url.callback
            if self.log:
                print "Processing: %s(%s): %s" %\
                        (url_regex.pattern,
                            url_regex.groupindex, view.__name__) 
            
            request = create_request(self.user, self.method) 
            kwargs = call_view(self.url, request, self.assignment_patterns)        
            
            if self.log:
                print "Running %s(%s)." % (view.__name__, kwargs)
            else:
                print "Running %s." % (view.__name__) 
            try:
                view(*(), **kwargs)
            except Http404, err:
                print "%s - A 404 occurred: %s" % (view.__name__, err)
                print "Please check the setUp of this test."
            except NotImplementedError, err:
                print "%s - NOT IMPLEMENTED: %s" % (view.__name__, err)
            
            if self.log:
                print "\n"

        

class Runner(unittest.TestCase):
    
    def __init__(self, states = []):
        self.states = states
        
    def add(self, state):
        self.states.append(state)
        
    def setUp(self):
        for s in self.states:
            s.set_up()
    
    def tearDown(self):
        for s in self.states:
            s.tear_down()
    
    def runTest(self):
        for s in self.states:
            s.run()
            s.verify()
    